#include "Vector3D.h"
#include "math.h"

namespace RayTracer
{
    float Vector3D::Dot(const Vector3D *l, const Vector3D *r)
    {
		return DOTP(l, r);
    }
		
    float Vector3D::Length(const Vector3D *vector)
    {	
		return (float)sqrt(DOTP(vector, vector));
    }
		
    void Vector3D::Normalize(Vector3D *vector)
    {
		float len = Vector3D::Length(vector);
		vector->x /= len;
		vector->y /= len;
		vector->z /= len;
    }
		
    Vector3D Vector3D::Add(const Vector3D *l, const Vector3D *r)
    {
		return Vector3D(l->x + r->x, l->y + r->y, l->z + r->z);
    }

	Vector3D Vector3D::Add(const Vector3D *l, float scalar)
    {
		return Vector3D(l->x + scalar, l->y + scalar, l->z + scalar);
    }

	Vector3D Vector3D::MultiplyN(const Vector3D *l, const Vector3D *r)
	{
		return Vector3D(l->x * r->x, l->y * r->y, l->z * r->z);
	}

	void Vector3D::Multiply(Vector3D *vector, float scale)
    {
		vector->x *= scale;
		vector->y *= scale;
		vector->z *= scale;
    }

	Vector3D Vector3D::MultiplyN(const Vector3D *vector, float scale)
    {
		Vector3D res = Vector3D(*vector);
		Vector3D::Multiply(&res, scale);
			
		return res;
    }
		
    Vector3D Vector3D::Subtract(const Vector3D *l, const Vector3D *r)
    {
		return Vector3D(l->x - r->x, l->y - r->y, l->z - r->z);
    }

	Vector3D Vector3D::Subtract(const Vector3D *l, float scalar)
    {
		return Vector3D(l->x - scalar, l->y - scalar, l->z - scalar);
    }
		
    Vector3D Vector3D::Cross(const Vector3D *l, const Vector3D *r)
    {
		return Vector3D(l->y * r->z - l->z * r->y, l->z * r->x - l->x * r->z, l->x * r->y - l->y * r->x);
    }

    Vector3D Vector3D::Empty()
    {
		return Vector3D();
    }
		
    Vector3D::Vector3D() : x(0), y(0), z(0)
    {
    }
		
    Vector3D::Vector3D(float x, float y, float z) : x(x), y(y), z(z)
    {
    }
		
    Vector3D::Vector3D(const Vector3D &prototype)
    {
		this->x = prototype.x;
		this->y = prototype.y;
		this->z = prototype.z;
    }
};
